import pyautogui as pg
import os
import time
import pyperclip
import requests
import json
import psutil
import sys
import win32gui, win32com.client
import win32con
import win32process  
import ctypes
from pywinauto.application import Application



def enum_child_windows(hwnd, result):  
    result.append((hwnd, win32gui.GetWindowText(hwnd)))  

def set_foreground_window(hwnd):  
    _, pid = win32process.GetWindowThreadProcessId(hwnd)  
    ctypes.windll.user32.AllowSetForegroundWindow(pid)  
    shell = win32com.client.Dispatch("WScript.Shell")
    shell.SendKeys('%{1}')
    win32gui.SetForegroundWindow(hwnd)  

def reset_softWare_Default():
    time.sleep(7)
    pg.hotkey("tab")
    pg.hotkey("tab")
    pg.hotkey("shift", "F10")
    pg.hotkey("up")
    pg.hotkey("enter")
    time.sleep(1)
    pg.hotkey("right")
    pg.hotkey("enter")
    pg.hotkey("left")
    pg.hotkey("enter")
    pg.hotkey("right")
    pg.hotkey("enter")


def check_project_number_is_null():
    time.sleep(5)
    # pg.hotkey("tab")
    # pg.hotkey("tab")
    pyperclip.copy("2")
    pg.hotkey("right")
    time.sleep(1)
    pg.hotkey("right")
    # 解锁单元格
    pg.hotkey("shift", "F10")
    pg.hotkey("w")
    pg.hotkey("space")
    pg.hotkey("ctrl", "c")
    number = pyperclip.paste()
    if number != "2" :
        return
    else :
        i = 1
        retry = 0
        while True :
            pyperclip.copy("2")
            pg.hotkey("ctrl", "c")
            pre_number = pyperclip.paste()
            if (pre_number != "2" and pre_number != " " and pre_number != "  ") :
                retry += 1
                i -= 1
                if retry >= 2 :
                    break
            # pyperclip.copy("1")
            time.sleep(0.5)
            # pg.hotkey("ctrl", "v")
            pg.typewrite("1")
            if i == 1 :
                pyperclip.copy("2")
                # 检测是否输入成功
                time.sleep(1)
                pg.hotkey("ctrl", "a")
                pg.hotkey("ctrl", "c")
                # print(pyperclip.paste())none
                if (pyperclip.paste() != "1") :
                    pg.hotkey("enter")
                    pg.hotkey("right")
                    time.sleep(0.5)
                    # 解锁单元格
                    pg.hotkey("shift", "F10")
                    pg.hotkey("w")
                    pg.hotkey("space")
                    continue
            pg.hotkey("enter")
            pg.hotkey("down")
            time.sleep(0.5)
            # 解锁单元格
            pg.hotkey("shift", "F10")
            pg.hotkey("w")
            pg.hotkey("space")
            time.sleep(0.5)
            if i > 200:
                raise Exception('too many project numbers need to be filled in')
            i += 1


# 扫描指定目录下的文件，运行名称里有QDJJ或者以斯维尔清单开头的文件
def open_software(dir_path) :
    file_list = os.listdir(dir_path)
    list = []
    for file_name in file_list :
        if (file_name.startswith("斯维尔清单") or "QDJJ" in file_name):
            list.append(file_name)
    os.startfile(dir_path + "\\" + list[0])


def close_tips():
    time.sleep(7)
    tips = win32gui.FindWindow(None, "提示")
    if tips:
        # win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
        print(f"窗口句柄为：{tips}")
        title = win32gui.GetWindowText(tips)
        clsname = win32gui.GetClassName(tips)
        print(title + clsname)
        win32gui.SendMessage(tips, win32con.WM_CLOSE, 0, 0)
    else:
        print("tips : 未找到指定窗口")
        # raise Exception('tips : 未找到指定窗口句柄')

def close_tutor():
    time.sleep(3)
    tutor = win32gui.FindWindow(None, "新建向导")
    if tutor:
        win32gui.SendMessage(tutor, win32con.WM_CLOSE, 0, 0)
        print(f"窗口句柄为：{tutor}")
    else:
        print("新建向导 : 未找到指定窗口")
    tutor = win32gui.FindWindow(None, "新建向导")
    if tutor:
        win32gui.SendMessage(tutor, win32con.WM_CLOSE, 0, 0)
        print(f"窗口句柄为：{tutor}")
    else:
        print("新建向导 : 未找到指定窗口")

def open_file(target_file_path):
    if not os.path.exists(target_file_path) :
        raise Exception ("cant not find file")
    hwnd = win32gui.FindWindow(None, "斯维尔清单计价 TH-BQ2016 标准版")
    if hwnd:
        # win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
        print(f"窗口句柄为：{hwnd}")
    else:
        print("未找到指定窗口")
    menu = win32gui.GetMenu(hwnd)
    menu1 = win32gui.GetSubMenu(menu, 0)#第几个菜单
    cmd_ID = win32gui.GetMenuItemID(menu1, 1)#第几个子菜单
    win32gui.PostMessage(hwnd, win32con.WM_COMMAND, cmd_ID, 0)
    time.sleep(2)
    open = win32gui.FindWindow(None, "打开")
    if open:
        # win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
        print(f"打开窗口句柄为：{open}")
        time.sleep(1)
    else:
        print("打开未找到指定窗口")
    child_windows = []  
    win32gui.EnumChildWindows(open, enum_child_windows, child_windows)  
    # print(len(child_windows))
    # 假设我们找到了一个类名为 'EDIT' 的子窗口（通常编辑框的类名）  
    edit_hwnd = None  
    confirm_hwnd = None
    for hwnd_child, window_text_child in child_windows:  
        # print(str(hwnd_child) + " " + win32gui.GetClassName(hwnd_child) + " " + win32gui.GetWindowText(hwnd_child))
        if win32gui.GetClassName(hwnd_child) == 'Edit':  
            edit_hwnd = hwnd_child  
    win32gui.SendMessage(edit_hwnd, win32con.WM_SETTEXT, 0, target_file_path)
    set_foreground_window(open)
    # win32gui.SetFocus(open)
    pg.hotkey("Enter")
    time.sleep(3)
    return hwnd


def check_version():
    time.sleep(5)
    version_tips = win32gui.FindWindow(None, "提示")
    if (version_tips is not None and version_tips != 0):
        raise Exception("jia mi")

def check_precision():
    time.sleep(5)
    check = win32gui.FindWindow(None, "询问")
    print(check)
    if check is not None and check != 0:
        pg.hotkey("Enter")
        i = 0
        while (i < 50):
            suc_tips = win32gui.FindWindow(None, "提示")
            if suc_tips != None and suc_tips != 0:
                win32gui.SendMessage(suc_tips, win32con.WM_CLOSE, 0, 0)
                break;
            i = i + 1
            time.sleep(5)



def export_file(hwnd):
    app = Application(backend='uia').connect(handle=hwnd)
    dlg = app.window(title=win32gui.GetWindowText(hwnd))  # 根据你的窗口标题进行调整  

    elec_book = dlg.child_window(title="电子标书", control_type="TabItem")
    elec_book.click_input()

    pg.hotkey("tab")
    pg.hotkey("left")
    pg.hotkey("down")
    pg.hotkey("down")

    generate = dlg.child_window(title="生成标书", control_type="Button")
    generate.click_input()
    pg.hotkey("down")
    pg.hotkey("Enter")
    time.sleep(1)
    number_eror = win32gui.FindWindow(None, "提示")
    if number_eror is not None and number_eror != 0:
        raise Exception("bian hao tian xie cuo wu")
    

def fill_author_info():
    time.sleep(1)
    author_hwnd = win32gui.FindWindow(None, "项目信息检测")
    print("项目信息" + str(author_hwnd))
    if (author_hwnd) :
        pg.hotkey("right")
        count = 0
        while True :
            pyperclip.copy("1")
            pg.hotkey("ctrl", "v")
            pg.hotkey("enter")
            pg.hotkey("down")
            pg.hotkey("space")
            count += 1
            if (count > 6):
                break
        pg.hotkey("tab")
        pg.hotkey("enter")


def do_export(id):
    time.sleep(2)
    another = win32gui.FindWindow(None, "另存为")
    # child_windows = []  
    # print(len(child_windows))
    # 假设我们找到了一个类名为 'EDIT' 的子窗口（通常编辑框的类名）  
    if another:
        edit_hwnd = None
        edit_text = None
        time.sleep(1)
        xml_file_name = str(id) + ".xml"
        set_foreground_window(another)
        pg.typewrite(xml_file_name)
        pg.hotkey("enter")
        time.sleep(1)
        error = win32gui.FindWindow(None, "错误")
        if error:
            raise Exception("export_error")
        time.sleep(1)
        confirm = win32gui.FindWindow(None, "确认另存为")
        if confirm:
            pg.hotkey("left")
            pg.hotkey("enter")
    else :
        raise Exception("bian hao tian xie cuo wu")
    return xml_file_name

def check_success():
    while True :
        time.sleep(5)
        # 导出成功
        success_hwnd = win32gui.FindWindow(None, "提示")
        if success_hwnd:
            return
        error = win32gui.FindWindow(None, "错误")
        if error:
            raise Exception("export error")
        time.sleep(1)


# 关闭软件
def close_software():
    pids = psutil.pids()
    for pid in pids:
        p = psutil.Process(pid)
        process_name = p.name()
        if process_name.startswith('QDJJ'):
            # 杀掉指定进程
            # print('kill process: name: %s - pid: %s' %(process_name, pid))
            find_kill = 'taskkill -f -pid %s' % pid
            os.popen(find_kill)

# 导出成功
def export_success(id, file_name):
    url = '''http://127.0.0.1:9135/rpa/runSuccess'''
    data = {
        "id" : id,
        "file_name" : file_name
    }
    headers = {
        'Content-Type': 'application/json'
    }
    requests.post(url = url, data = json.dumps(data), headers= headers)


# 异常处理
def export_failed(id, errorMsg):
    url = '''http://127.0.0.1:9135/rpa/runFailed'''
    data = {
        "id" : id,
        "errMsg": errorMsg
    }
    headers = {
        'Content-Type': 'application/json'
    }
    requests.post(url = url, data = json.dumps(data), headers=headers)



pg.FAILSAFE = False 

# 程序被唤起 参数为文件本地地址 文件id
dir_path = sys.argv[1]
need_export_file_name = sys.argv[2]
id = int(sys.argv[3])

try :
    close_software()
    time.sleep(1)
    # 桌面软件地址
    software_path = 'C:\\'
    # 打开导出桌面软件
    open_software(software_path)
    # 关闭提示
    close_tips()
    # 关闭新建向导
    close_tutor()
    hwnd = open_file(dir_path + need_export_file_name)
    check_version()
    check_precision()
    # 恢复软件默认设置
    reset_softWare_Default()
    check_project_number_is_null()
    # 执行点击流程导出软件
    export_file(hwnd)
    fill_author_info()
    xml_file_name = do_export(id)
    check_success()
    # print(xml_file_name)
    # 导出成功
    close_software()
    time.sleep(5)
    export_success(id, xml_file_name)
    # 检测到导出成功窗口后5秒关闭软件
except Exception as e:
    close_software()
    export_failed(id, str(e))
    time.sleep(5)